import 'dart:io';
import 'package:dio/dio.dart';
//import 'package:flutter/scheduler.dart';
import 'extra_keys.dart';
import 'response_data.dart';
import 'error_code.dart';
import '../model/public/oauth_model.dart';
import '../utils/shared_preferences.dart';
import '../api/token_api.dart' show refreshToken;

/// oauth2.0 认证/授权 拦截器
class OauthInterceptor extends QueuedInterceptor {
  @override
  void onRequest(
    RequestOptions options,
    RequestInterceptorHandler handler,
  ) async {
    if (options.extra[ExtraKeys.NEED_TOKEN] == false) {
      return handler.next(options);
    }

    Map<String, dynamic>? tokenObj = SpUtil.getObject(SPKeys.TOKEN_KEY);
    // 如果token为空利用路由跳转登录页
    if (tokenObj == null) {
//      /// 防止页面未构建完跳转或弹出对话框报错: https://www.manongdao.com/article-311445.html
//      SchedulerBinding.instance.addPostFrameCallback((_) {
//        AppManager.showUnLoginDialog();
//      });

      // 中断当前请求
      _rejectNotLogin();
      return handler.next(options);
    }

    /// 过期需要刷新token
    OAuthModel token = OAuthModel.fromJson(tokenObj);
    try {
      // 再次判断token是否过期, 如果不过期则不需要刷新
      if (token.isExpire()) {
        /// 重试3次的方式, 获取最新token并保存到本地
        ResponseData refreshData = await refreshToken(token.refreshToken);
        // ResponseData refreshData = await retry3<ResponseData>(() => refreshToken(token.refreshToken));
        token = OAuthModel.fromJson(refreshData.data);
        SpUtil.putObject(SPKeys.TOKEN_KEY, token.toJson());
      }
    } on ResponseData catch (e) {
      // 如果刷新token失败. 可能是refreshToken失效了
      // 也可能是网络问题
      // 如果refreshToken失效需要跳转登录
      // 如果是网络问题需要重试
      // 网络异常, 比如超时, 无网络等.
      // 无法刷新, 直接提示错误, 放弃当前刷新请求待用户重试
      // 如果刷新token服务器端refresh_token失效, 清除token, 跳转到登录页面
      if (e.code == ErrorCode.REFRESH_INVALID.code) {
//          /// 防止页面未构建完跳转或弹出对话框报错
//          SchedulerBinding.instance.addPostFrameCallback((_) {
//            // 该处使用场景可以是app默认需要登录
//            // AppManager.goLogin();
//            AppManager.showUnLoginDialog();
//          });
        // 中断当前请求
        _rejectNotLogin();
        return handler.next(options);
      }
    }
    options.headers[HttpHeaders.authorizationHeader] =
        "Bearer ${token.accessToken}";
    return handler.next(options);
  }

  /// 抛出未登录的异常
  void _rejectNotLogin() {
    // 清除token
    SpUtil.remove(SPKeys.TOKEN_KEY);
    SpUtil.remove(SPKeys.USER_INFO);
  }
}
